package help;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import object.TestObject;
import bus.AccountBUS;
import bus.AnswerBUS;
import bus.PatientBUS;
import bus.QuestionBUS;
import bus.ScoreBUS;
import bus.TestBUS;
import bus.TestDetailBUS;
import bus.TestScoreBUS;
import bus.TitleBUS;
import dto.AccountDTO;
import dto.AnswerDTO;
import dto.PatientDTO;
import dto.QuestionDTO;
import dto.ScoreDTO;
import dto.TestDTO;
import dto.TestDetailDTO;
import dto.TestScoreDTO;
import dto.TitleDTO;


public class Utility {
	
	public static List<AccountDTO> lstAccountDTO;
	public static List<TitleDTO> lstTitleDTO;
	public static int currentIndex;
	public static SurveyObject currentSurvey;
	
	public static void init()
	{														
		initListAccount();
		initListTitle();
		currentSurvey = new SurveyObject();
	}
	private static void initListAccount() 
	{
		AccountBUS accountBUS = new AccountBUS();
		List<AccountDTO> accountList = new ArrayList<AccountDTO>();
		accountList = accountBUS.getAllAccounts();
		lstAccountDTO = new ArrayList<AccountDTO>();
		
		for (int i = 0; i < accountList.size(); i++)
		{
			lstAccountDTO.add(accountList.get(i));
		}
	}
	private static void initListTitle() {
		TitleBUS titleBUS = new TitleBUS();
		lstTitleDTO = new ArrayList<TitleDTO>();
		lstTitleDTO = titleBUS.getAllTitles();
		
		AnswerBUS answerBUS = new AnswerBUS();
		List<AnswerDTO> lstAnswer = new ArrayList<AnswerDTO>();
		lstAnswer = answerBUS.getAllAnswers();
		for (AnswerDTO answer : lstAnswer) {
			for (TitleDTO title : lstTitleDTO) {
				if (title.getID() == answer.getTitleID()) {
					title.lstAnswer.add(answer);
					break;
				}
			}
		}
		
		ScoreBUS scoreBUS = new ScoreBUS();
		List<ScoreDTO> lstScore = new ArrayList<ScoreDTO>();
		lstScore = scoreBUS.getAllScores();
		
		QuestionBUS questionBUS = new QuestionBUS();
		List<QuestionDTO> lstQuestion = new ArrayList<QuestionDTO>();
		lstQuestion = questionBUS.getAllQuestions();
		for (QuestionDTO question : lstQuestion) {
			for (TitleDTO title : lstTitleDTO) {
				if (title.getID() == question.getTitleID()) {
					question.lstScore = getListScore(lstScore, question.getID(), title.getAnswerSize());
					title.lstQuestion.add(question);
					break;
				}
			}
		}
	}
	private static List<ScoreDTO> getListScore(List<ScoreDTO> lstScore, int questionID, int noAnswer) {
		List<ScoreDTO> lst = new ArrayList<ScoreDTO>();
		int count = 0;
		for (int i = 0; i < lstScore.size(); i++) {
			if (count == noAnswer) {
				break;
			}
			else {
				if (lstScore.get(i).getQuestionID() == questionID) {
					lst.add(lstScore.get(i));
					count++;
				}
			}
		}
		return lst;
	}
	
	public static AccountDTO currentAccount() {
		if (currentIndex >= 0 && currentIndex < lstAccountDTO.size())
			return lstAccountDTO.get(currentIndex);
		return null;
	}
	
	private static void updateCurrentAccount(AccountDTO account) {
		lstAccountDTO.get(currentIndex).update(account);
	}
	
	public static int signIn(String email, String password) {
		if (email.isEmpty() || password.isEmpty()) {
			return Define.kEmpty;
		}
		for (int i = 0; i < Utility.lstAccountDTO.size(); i++) {
			AccountDTO account = Utility.lstAccountDTO.get(i);
			if (account.getEmail().equals(email) == true) {
				if (account.getPassword().equals(password) == true) {
					Utility.currentIndex = i;
					return Define.kSuccess;
				}
			}
		}
		
		return Define.kFail;
	}
	
	public static int signUp(String email, String password, String confirm, String firstname, String lastname, boolean isCheckTerm) {
		if (isCheckTerm == true) {
			if (email.isEmpty() || password.isEmpty() || confirm.isEmpty() || firstname.isEmpty() || lastname.isEmpty()) {
				return Define.kEmpty;
			}
			else {
				if (password.equals(confirm) == false) {
					return Define.kUnMatch;
				}
				for (AccountDTO account : Utility.lstAccountDTO) {
					if (account.getEmail().equals(email)) {
						return Define.kExist;
					}
				}
				
				AccountDTO account = new AccountDTO(0, email, password, firstname, lastname, false);
				AccountBUS accountBUS = new AccountBUS();
				accountBUS.setInfo(account);
				accountBUS.addAccount();
				Utility.initListAccount();
				return Define.kSuccess;
			}
		}

		return Define.kUnCheck;
	}
	
	public static void signOut() {
		currentIndex = -1;
	}

	public static int changeEmail(String email) {
		if (email.isEmpty())
			return Define.kEmpty;
		
		if (Utility.currentAccount().getEmail().equals(email)) {
			return Define.kExist;
		}
		
		for (AccountDTO account : Utility.lstAccountDTO) {
			if (account.getEmail().equals(email)) {
				return Define.kExist;
			}
		}
		AccountDTO account = new AccountDTO(Utility.currentAccount());
		account.setEmail(email);
		AccountBUS accountBUS = new AccountBUS();
		accountBUS.setInfo(account);
		
		if (accountBUS.updateAccount()) {
			Utility.updateCurrentAccount(account);
			return Define.kSuccess;
		}

		return Define.kFail;
	}

	public static int changePassword(String oldPassword, String newPassword, String confirmPassword) {
		if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmPassword.isEmpty())
			return Define.kEmpty;
		
		if (newPassword.equals(oldPassword)) {
			return Define.kUnDifference;
		}
		if (Utility.currentAccount().getPassword().equals(oldPassword)) {
			if (newPassword.equals(confirmPassword)) {
				AccountDTO account = new AccountDTO(Utility.currentAccount());
				account.setPassword(newPassword);
				AccountBUS accountBUS = new AccountBUS();
				accountBUS.setInfo(account);
				if (accountBUS.updateAccount()) {
					Utility.updateCurrentAccount(account);
					return Define.kSuccess;
				}

				return Define.kFail;
			}

			return Define.kUnMatch;
		}

		return Define.kEmpty;
	}

	public static int changePersonalInfo(String firstname, String lastname) {
		if (firstname.isEmpty() || lastname.isEmpty()) {
			return Define.kEmpty;
		}
		AccountDTO account = new AccountDTO(Utility.currentAccount());
		account.setFirstname(firstname);
		account.setLastname(lastname);
		AccountBUS accountBUS = new AccountBUS();
		accountBUS.setInfo(account);
		if (accountBUS.updateAccount()) {
			Utility.updateCurrentAccount(account);
			return Define.kSuccess;
		}
		else {
			return Define.kFail;
		}
	}

	public static int createPatient(String firstname, String surname, String age, boolean gender) {
		if (firstname.isEmpty() || surname.isEmpty() || age.isEmpty()) {
			return Define.kEmpty;
		}
		
		int iAge = Integer.parseInt(age);
		PatientBUS patientBUS = new PatientBUS();
		PatientDTO patientDTO = new PatientDTO(0, firstname, surname, iAge, gender);
		patientBUS.setInfo(patientDTO);
		int id = patientBUS.addPatient();
		if (id != -1) {
			patientDTO.setID(id);
			currentSurvey.Reset();
			currentSurvey.patient = new PatientDTO(patientDTO);
			
			TestBUS testBUS = new TestBUS();
			TestDTO testDTO = new TestDTO(0, new Date(System.currentTimeMillis()), Utility.lstAccountDTO.get(currentIndex).getID(), currentSurvey.patient.getID());
			testBUS.setInfo(testDTO);
			int testID = testBUS.addTest();
			if (testID != -1) {
				testDTO.setID(testID);
				currentSurvey.test = new TestDTO(testDTO);
				return Define.kSuccess;
			}
			return Define.kFail;
		}
		
		return Define.kFail;
	}

	public static void createTestDetail(List<TestObject> lstTestObject, int titleID) {
		int totalScore = 0;
		for (TestObject testObj : lstTestObject) {
			int score = testObj.getScore();
			totalScore += score;
			TestDetailDTO testDetailDTO = new TestDetailDTO(0, currentSurvey.test.getID(), testObj.getQuestionID(), testObj.getAnswerID(), score);
			TestDetailBUS testDetailBUS = new TestDetailBUS();
			testDetailBUS.setInfo(testDetailDTO);
			testDetailBUS.addTestDetail();
		}
		
		TestScoreDTO testScoreDTO = new TestScoreDTO(0, currentSurvey.test.getID(), titleID, totalScore);
		TestScoreBUS testScoreBUS = new TestScoreBUS();
		testScoreBUS.setInfo(testScoreDTO);
		testScoreBUS.addTestScore();
	}

}
